import $util from '../utils/util.js'
import utils from '../utils/util.js'

export default {
	name: "ClinkBlood",
	primaryUuid: "0000FC00-0000-1000-8000-00805F9B34FB",
	writeUuid: "0000FCA0-0000-1000-8000-00805F9B34FB",
	notifyUuid: "0000FCA1-0000-1000-8000-00805F9B34FB",
	bpDeviceInfo: '',
	isConnect: false,
	result: {
		highPressure: 0,
		lowPressure: 0,
		heartRate: 0,
	},
	deviceType: 0,
	callback: '',
	progressCallback: '',
	startCount: 0,
	isReadResult: false,
	isSetListener: false,
	isBloodPressure: false,
	startBloodPressure(progress, result) {
		this.callback = result;
		this.progressCallback = progress;
		this.isReadResult = false;
		let _this = this;
		uni.getBluetoothDevices({
			success(res) {
				console.log("getBluetoothDevices success res: ", res);
				let devices = res.devices;
				let isFind = false;
				for (var i = 0; i < devices.length; i++) {
					let item = devices[i];
					console.log(item.name.replace(/\s*/g, ""));
					console.log(_this.name);
					console.log(JSON.stringify(item.advertisServiceUUIDs));
					if (item.name.replace(/\s*/g, "") == _this.name) {
						_this.bpDeviceInfo = item;
						isFind = true;
						/* for (var j = 0; j < item.advertisServiceUUIDs.length; j++) {
							// if (item.advertisServiceUUIDs[j].toLowerCase() == _this.primaryUuid) {
							if (item.advertisServiceUUIDs[j] == _this.primaryUuid) {
								//console.log("advertisServiceUUIDs:",JSON.stringify(item.advertisServiceUUIDs));
								_this.bpDeviceInfo = item;
								isFind = true;
								break;
							}
						} */
						if (isFind) {
							break;
						}
					}
				}
				if (!$util.isNullOrEmpty(_this.bpDeviceInfo)) {
					_this.startCount = 0;
					_this.setConnectListener();
					console.log(JSON.stringify(_this.bpDeviceInfo));
					_this.createConnect(_this.bpDeviceInfo.deviceId);
				} else {
					setTimeout(() => {
						if (_this.startCount < 10) {
							_this.startBloodPressure(progress, result)
							_this.startCount++;
						} else {
							_this.startCount = 0;
							_this.progressCallback({
								succeed: false,
								message: '启动失败，请检查血压仪是否开启？'
							});
						}
					}, 1000);
				}
			},
			fail(res) {
				//console.log("getBluetoothDevices fail res: ", res);
				_this.progressCallback({
					succeed: false,
					message: '启动失败，请检查血压仪是否开启？'
				});
			}
		})
	},
	createConnect(deviceId) {
		let _this = this;
		uni.createBLEConnection({
			deviceId: deviceId,
			success(res) {
				console.log("connect success res: ", res);
				// _this.setConnectListener();

			},
			fail(res) {
				//console.log("connect fail res: ", res);
				_this.progressCallback({
					succeed: false,
					message: '启动失败，请检查蓝牙或者血压仪是否开启？'
				});
			}
		})
	},
	closeConnect(deviceId) {
		let _this = this;
		if (!this.isConnect) {
			//console.log("not connect.");
			return;
		}
		uni.closeBLEConnection({
			deviceId: deviceId,
			success(res) {
				//console.log("close success res: ", res);
				_this.isConnect = false;
			},
			fail(res) {
				//console.log("close fail res: ", res);
			}
		})
		_this.isSetListener = false;
	},
	getServices(deviceId) {
		let _this = this;
		uni.getBLEDeviceServices({
			deviceId: deviceId,
			success(servicedata) {
				console.log("services success res: ", servicedata);
				if (servicedata.services.length <= 0) {
					setTimeout(() => {
						_this.getServices(deviceId);
					}, 1000);
				} else {
					console.log("services-uuid：" + servicedata.services[0].uuid);
					_this.getBLEDeviceCharacteristics(deviceId)

				}
			},
			fail(res) {
				//console.log("services fail res: ", res);
				_this.progressCallback({
					succeed: false,
					message: '启动失败，请检查蓝牙或者血压仪是否开启？'
				});
			}
		})
	},
	getBLEDeviceCharacteristics(deviceId) {
		let _this = this;
		// console.log("services："+ _this.primaryUuid);
		uni.getBLEDeviceCharacteristics({
			deviceId: deviceId,
			serviceId: _this.primaryUuid,
			success(Character) {
				console.log('getBLEDeviceCharacteristics success res:', Character)
				_this.writeBLECharacteristicValue(deviceId)
			},
			fail(res) {
				_this.progressCallback({
					succeed: false,
					message: '启动失败，请检查蓝牙或者血压仪是否开启？'
				});
				console.log("readBLECharacteristicValue fail res: ", res);
			}
		})
	},
	writeBLECharacteristicValue(deviceId) {
		let _this = this;
		var a =utils.hexStringToArrayBuffer("04b0a054");
		uni.writeBLECharacteristicValue({
			deviceId: deviceId,
			serviceId: _this.primaryUuid,
			characteristicId: "0000FCA0-0000-1000-8000-00805F9B34FB",
			value: a,
			success: function() {
				console.log("发送指令成功！！！")
				console.log("deviceId"+ deviceId);
				console.log("serviceId"+ _this.primaryUuid);
				
				setTimeout(function() { 
					_this.notifyBLECharacteristicValueChange(deviceId)
				}, 1000);
				
			},
			fail: function(e) {
				console.log("发送失败" + e.errMsg + "\n")
			}
		})
	},

	notifyBLECharacteristicValueChange(deviceId) {
		let _this = this;

		uni.notifyBLECharacteristicValueChange({
			state: true, // 启用 notify 功能
			deviceId: deviceId,
			serviceId: _this.primaryUuid,
			characteristicId: _this.notifyUuid,
			success(res) {
				_this.progressCallback({ 
					succeed: true,
					message: '血压仪已启动，请耐心等待...'
				});
				//console.log('notifyBLECharacteristicValueChange success res', res);
				// 必须在这里的回调才能获取
				if (!_this.isSetListener) {
					console.log("notify");
					console.log("deviceId"+ deviceId);
					console.log("serviceId"+ _this.primaryUuid);
					console.log("characteristicId"+ _this.notifyUuid);
					uni.onBLECharacteristicValueChange(function(res) {
						console.log(JSON.stringify(res));
						if (_this.isBloodPressure) {
							_this.getData(deviceId, res.value);
						}
					});
					_this.isSetListener = true; 
					
					
				}
			},
			fail(res) {
				_this.progressCallback({
					succeed: false,
					message: '启动失败，请检查蓝牙或者血压仪是否开启？'
				});
				console.log("notifyBLECharacteristicValueChange fail res: ", res);
			}
		});
		//此处自动启动血压测量
		setTimeout(() => {
			_this.sendData(deviceId);
		}, 500);
	},
	setConnectListener() {
		let _this = this;
		uni.onBLEConnectionStateChange(function(res) {
			console.log("setConnectListener res: ", res);
			if (!_this.isBloodPressure) {
				//console.log("not  BloodPressure: ");
				return;
			}
			_this.isConnect = res.connected;
			if (res.connected && res.deviceId == _this.bpDeviceInfo.deviceId) {
				uni.setBLEMTU({
					deviceId: res.deviceId,
					mtu: 512,
					success(res) {
						//console.log("setBLEMTU success res: ", res);
					},
					fail(res) {
						//console.log("setBLEMTU fail res: ", res);
					}
				})
				_this.getServices(res.deviceId);
			} else if (!_this.isReadResult) {
				_this.progressCallback({
					succeed: false,
					message: '启动失败，请检查蓝牙或者血压仪是否开启？'
				});
			}
		})
	},
	sendData(deviceId) {
		// 向蓝牙设备发送一个0x00的16进制数据
		const date = new Date();
		let year = date.getYear() + 1900 - 2000;
		let month = date.getMonth() + 1;
		let day = date.getDate();
		let hours = date.getHours();
		let minutes = date.getMinutes();
		const buffer = new ArrayBuffer(11);
		const dataView = new DataView(buffer);
		dataView.setUint8(0, 0x5A); //head
		dataView.setUint8(1, 0x0B); //length
		dataView.setUint8(2, 0x05); //cmdSort
		dataView.setUint8(3, year);
		dataView.setUint8(4, month);
		dataView.setUint8(5, day);
		dataView.setUint8(6, hours);
		dataView.setUint8(7, minutes);
		var cmdCheck = 0;
		for (var i = 0; i < buffer.byteLength; i++) {
			cmdCheck += dataView.getUint8(i);
		}
		var byteCmd = this.unsigned2signed(cmdCheck);
		dataView.setUint8(8, byteCmd);
		dataView.setUint8(9, 0);

		let _this = this;
		uni.writeBLECharacteristicValue({
			deviceId: deviceId,
			serviceId: _this.primaryUuid,
			characteristicId: _this.writeUuid,
			value: buffer,
			success(res) {
				//console.log("write success res: ", res);
			},
			fail(res) {
				//console.log("write fail res: ", res);
			}
		})
	},
	unsigned2signed(unsigned) {
		var value = parseInt(unsigned, 10);
		if (value > 256)
			return value % 256;
		var temp = []; //10进制转换为2进制字符串
		while (value > 0) {
			if (value % 2 != 0) {
				temp.push(1);
			} else {
				temp.push(0);
			}
			value = parseInt(value / 2);
		}
		//不足8位再前方做补0操作
		temp.reverse();
		while (temp.length < 8) {
			temp.unshift(0)
		}
		temp = temp.join('');
		var signed = ''; //无符号转有符号字节 取该二进制字符串补码即可
		if (temp.substr(0, 1) == 1) { //二进制符号位等于1 则有符号
			for (var i = 1; i < temp.length; i++) {
				temp.substr(i, 1) == 1 ? signed += 0 : signed += 1;
			}
			return ('-' + (parseInt(signed, 2) + 1));
		} else {
			for (var i = 0; i < temp.length; i++) {
				signed += temp.substr(i, 1); //源码输出
			}
			return (parseInt(signed, 2));
		}
	},
	getData(deviceId, buffer) {
		let _this = this;
		if ($util.isNullOrEmpty(buffer)) {
			//console.log("getData buffer: ", buffer);
			return;
		}
		const dataView = new DataView(buffer);
		if (dataView.getUint8(0) === 0x55) {
			let length = dataView.byteLength;
			if (length >= 10 && dataView.getUint8(1) === 0x10 && dataView.getUint8(2) === 0) {
				_this.deviceType = dataView.getUint8(5); //1血压，2血糖
				setTimeout(() => {
					_this.sendData(deviceId);
				}, 300);
			}
			// //console.log("deviceType: ", _this.deviceType);
			if (_this.deviceType === 1) {
				if (length === 6 && dataView.getUint8(1) === 0x06) {
					if (dataView.getUint8(2) === 1) { //开始包
						setTimeout(() => {
							_this.sendData(deviceId);
						}, 300);
					} else if (dataView.getUint8(2) === 4) { //结束包
						//console.log("finish package: ", dataView.getUint8(2));
					}
				} else if (length >= 13 && dataView.getUint8(1) === 0x0f && dataView.getUint8(2) === 3) {
					//血压结果
					_this.getDeviceData(_this.deviceType, dataView, deviceId);
					_this.sendData(deviceId);
				}
			}
		}
	},
	getDeviceData(deviceType, dataView, deviceId) {
		if (deviceType === 1) { //1血压
			if (dataView.byteLength > 11) {
				let high = this.getShort(dataView, 8);
				let low = dataView.getUint8(10);
				let rate = dataView.getUint8(11);
				let readResult = "高压：" + high + " 低：" + low + " 心：" + rate;
				//console.log("this.readResult: ", readResult);
				this.result.highPressure = high;
				this.result.lowPressure = low;
				this.result.heartRate = rate;
				if (!this.isReadResult) {
					this.callback(this.result);
				}
				this.isReadResult = true;
				this.result.highPressure = 0;
				this.result.lowPressure = 0;
				this.result.heartRate = 0;
			}
		}
	},
	getShort(dataView, index) {
		return ((dataView.getUint8(index + 1) << 8) | dataView.getUint8(index) & 0xff)
	}
}
